home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2001 Spring / Oh!X 2001 Spring Special CD-ROM (Japan).7z / Oh!X 2001 Spring Special CD-ROM (Japan) (Track 1).bin / GALAXY / ohx5-2 / ddutil.cpp < prev    next >
C/C++ Source or Header  |  2000-01-22  |  12KB  |  359 lines

  1. //-----------------------------------------------------------------------------
  2. // File: ddutil.cpp
  3. //
  4. // Desc: Routines for loading bitmap and palettes from resources
  5. //
  6. //
  7. // Copyright (c) 1995-1999 Microsoft Corporation. All rights reserved.
  8. //-----------------------------------------------------------------------------
  9.  
  10. #ifndef WIN32_LEAN_AND_MEAN
  11. #define WIN32_LEAN_AND_MEAN
  12. #endif
  13.  
  14. //-----------------------------------------------------------------------------
  15. // Include files
  16. //-----------------------------------------------------------------------------
  17. #include <windows.h>
  18. #include <windowsx.h>
  19. #include <ddraw.h>
  20. #include "ddutil.h"
  21.  
  22. //-----------------------------------------------------------------------------
  23. // Name: DDLoadBitmap()
  24. // Desc: Create a DirectDrawSurface from a bitmap resource.
  25. // Direct-Draw で使えるビットマップリソース(DirectDrawSurface)を得る。
  26. //-----------------------------------------------------------------------------
  27. extern "C" IDirectDrawSurface7 *
  28. DDLoadBitmap(IDirectDraw7 * pdd, LPCSTR szBitmap, int dx, int dy)
  29. {
  30.     HBITMAP                 hbm;
  31.     BITMAP                  bm;
  32.     DDSURFACEDESC2          ddsd;
  33.     IDirectDrawSurface7    *pdds;
  34.  
  35.     //
  36.     //  Try to load the bitmap as a resource, if that fails, try it as a file
  37.     //
  38.     hbm = (HBITMAP) LoadImage( GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx, dy, LR_CREATEDIBSECTION);
  39.     if (hbm == NULL) hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,  LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  40.     if (hbm == NULL) return NULL;
  41.     //
  42.     // Get size of the bitmap
  43.     //
  44.     GetObject(hbm, sizeof(bm), &bm);
  45.     //
  46.     // Create a DirectDrawSurface for this bitmap
  47.     //
  48.     ZeroMemory(&ddsd, sizeof(ddsd));
  49.     ddsd.dwSize = sizeof(ddsd);
  50.     ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
  51.     ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
  52.     ddsd.dwWidth = bm.bmWidth;
  53.     ddsd.dwHeight = bm.bmHeight;
  54.     if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
  55.         return NULL;
  56.     DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
  57.     DeleteObject(hbm);
  58.     return pdds;
  59. }
  60.  
  61.  
  62.  
  63.  
  64. //-----------------------------------------------------------------------------
  65. // Name: DDReLoadBitmap()
  66. // Desc: Load a bitmap from a file or resource into a directdraw surface.
  67. //       normaly used to re-load a surface after a restore.
  68. //-----------------------------------------------------------------------------
  69. HRESULT
  70. DDReLoadBitmap(IDirectDrawSurface7 * pdds, LPCSTR szBitmap)
  71. {
  72.     HBITMAP                 hbm;
  73.     HRESULT                 hr;
  74.  
  75.     //
  76.     //  Try to load the bitmap as a resource, if that fails, try it as a file
  77.     //
  78.     hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0,
  79.                               0, LR_CREATEDIBSECTION);
  80.     if (hbm == NULL)
  81.         hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
  82.                                   LR_LOADFROMFILE | LR_CREATEDIBSECTION);
  83.     if (hbm == NULL)
  84.     {
  85.         OutputDebugString("handle is null\n");
  86.         return E_FAIL;
  87.     }
  88.     hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
  89.     if (hr != DD_OK)
  90.     {
  91.         OutputDebugString("ddcopybitmap failed\n");
  92.     }
  93.     DeleteObject(hbm);
  94.     return hr;
  95. }
  96.  
  97.  
  98.  
  99.  
  100. //-----------------------------------------------------------------------------
  101. // Name: DDCopyBitmap()
  102. // Desc: Draw a bitmap into a DirectDrawSurface
  103. //-----------------------------------------------------------------------------
  104. extern "C" HRESULT
  105. DDCopyBitmap(IDirectDrawSurface7 * pdds, HBITMAP hbm, int x, int y, int dx, int dy)
  106. {
  107.     HDC                     hdcImage;
  108.     HDC                     hdc;
  109.     BITMAP                  bm;
  110.     DDSURFACEDESC2          ddsd;
  111.     HRESULT                 hr;
  112.  
  113.     if (hbm == NULL || pdds == NULL)
  114.         return E_FAIL;
  115.     //
  116.     // Make sure this surface is restored.
  117.     //
  118.     pdds->Restore();
  119.     //
  120.     // Select bitmap into a memoryDC so we can use it.
  121.     //
  122.     hdcImage = CreateCompatibleDC(NULL);
  123.     if (!hdcImage)
  124.         OutputDebugString("createcompatible dc failed\n");
  125.     SelectObject(hdcImage, hbm);
  126.     //
  127.     // Get size of the bitmap
  128.     //
  129.     GetObject(hbm, sizeof(bm), &bm);
  130.     dx = dx == 0 ? bm.bmWidth : dx;     // Use the passed size, unless zero
  131.     dy = dy == 0 ? bm.bmHeight : dy;
  132.     //
  133.     // Get size of surface.
  134.     //
  135.     ddsd.dwSize = sizeof(ddsd);
  136.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  137.     pdds->GetSurfaceDesc(&ddsd);
  138.  
  139.     if ((hr = pdds->GetDC(&hdc)) == DD_OK)
  140.     {
  141.         StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,
  142.                    dx, dy, SRCCOPY);
  143.         pdds->ReleaseDC(hdc);
  144.     }
  145.     DeleteDC(hdcImage);
  146.     return hr;
  147. }
  148.  
  149. //-----------------------------------------------------------------------------
  150. // Name: DDCopyBitmap()
  151. // Desc: Draw a bitmap into a DirectDrawSurface
  152. //-----------------------------------------------------------------------------
  153. extern "C" HRESULT
  154. DDCopyBitmap2(IDirectDrawSurface7 * pdds, HBITMAP hbm, int x, int y, int dx, int dy)
  155. {
  156.     HDC                     hdcImage;
  157.     HDC                     hdc;
  158.     BITMAP                  bm;
  159.     DDSURFACEDESC2          ddsd;
  160.     HRESULT                 hr;
  161.  
  162.     if (hbm == NULL || pdds == NULL)
  163.         return E_FAIL;
  164.     //
  165.     // Make sure this surface is restored.
  166.     //
  167.     pdds->Restore();
  168.     //
  169.     // Select bitmap into a memoryDC so we can use it.
  170.     //
  171.     hdcImage = CreateCompatibleDC(NULL);
  172.     if (!hdcImage)
  173.         OutputDebugString("createcompatible dc failed\n");
  174.     SelectObject(hdcImage, hbm);
  175.     //
  176.     // Get size of the bitmap
  177.     //
  178.     GetObject(hbm, sizeof(bm), &bm);
  179.     dx = dx == 0 ? bm.bmWidth : dx;     // Use the passed size, unless zero
  180.     dy = dy == 0 ? bm.bmHeight : dy;
  181.     //
  182.     // Get size of surface.
  183.     //
  184.     ddsd.dwSize = sizeof(ddsd);
  185.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  186.     pdds->GetSurfaceDesc(&ddsd);
  187.  
  188.     if ((hr = pdds->GetDC(&hdc)) == DD_OK)
  189.     {
  190.         StretchBlt(hdc, 0, 0, dx, dy, hdcImage, x, y,
  191.                    dx, dy, SRCCOPY);
  192.         pdds->ReleaseDC(hdc);
  193.     }
  194.     DeleteDC(hdcImage);
  195.     return hr;
  196. }
  197.  
  198.  
  199. //-----------------------------------------------------------------------------
  200. // Name: DDLoadPalette()
  201. // Desc: Create a DirectDraw palette object from a bitmap resource
  202. //       if the resource does not exist or NULL is passed create a
  203. //       default 332 palette.
  204. //-----------------------------------------------------------------------------
  205. extern "C" IDirectDrawPalette *
  206. DDLoadPalette(IDirectDraw7 * pdd, LPCSTR szBitmap)
  207. {
  208.     IDirectDrawPalette     *ddpal;
  209.     int                     i;
  210.     int                     n;
  211.     int                     fh;
  212.     HRSRC                   h;
  213.     LPBITMAPINFOHEADER      lpbi;
  214.     PALETTEENTRY            ape[256];
  215.     RGBQUAD                *prgb;
  216.  
  217.     //
  218.     // Build a 332 palette as the default.
  219.     //
  220.     for (i = 0; i < 256; i++)
  221.     {
  222.         ape[i].peRed = (BYTE) (((i >> 5) & 0x07) * 255 / 7);
  223.         ape[i].peGreen = (BYTE) (((i >> 2) & 0x07) * 255 / 7);
  224.         ape[i].peBlue = (BYTE) (((i >> 0) & 0x03) * 255 / 3);
  225.         ape[i].peFlags = (BYTE) 0;
  226.     }
  227.     //
  228.     // Get a pointer to the bitmap resource.
  229.     //
  230.     if (szBitmap && (h = FindResource(NULL, szBitmap, RT_BITMAP)))
  231.     {
  232.         lpbi = (LPBITMAPINFOHEADER) LockResource(LoadResource(NULL, h));
  233.         if (!lpbi)
  234.             OutputDebugString("lock resource failed\n");
  235.         prgb = (RGBQUAD *) ((BYTE *) lpbi + lpbi->biSize);
  236.         if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
  237.             n = 0;
  238.         else if (lpbi->biBitCount > 8)
  239.             n = 0;
  240.         else if (lpbi->biClrUsed == 0)
  241.             n = 1 << lpbi->biBitCount;
  242.         else
  243.             n = lpbi->biClrUsed;
  244.         //
  245.         //  A DIB color table has its colors stored BGR not RGB
  246.         //  so flip them around.
  247.         //
  248.         for (i = 0; i < n; i++)
  249.         {
  250.             ape[i].peRed = prgb[i].rgbRed;
  251.             ape[i].peGreen = prgb[i].rgbGreen;
  252.             ape[i].peBlue = prgb[i].rgbBlue;
  253.             ape[i].peFlags = 0;
  254.         }
  255.     }
  256.     else if (szBitmap && (fh = _lopen(szBitmap, OF_READ)) != -1)
  257.     {
  258.         BITMAPFILEHEADER        bf;
  259.         BITMAPINFOHEADER        bi;
  260.  
  261.         _lread(fh, &bf, sizeof(bf));
  262.         _lread(fh, &bi, sizeof(bi));
  263.         _lread(fh, ape, sizeof(ape));
  264.         _lclose(fh);
  265.         if (bi.biSize != sizeof(BITMAPINFOHEADER))
  266.             n = 0;
  267.         else if (bi.biBitCount > 8)
  268.             n = 0;
  269.         else if (bi.biClrUsed == 0)
  270.             n = 1 << bi.biBitCount;
  271.         else
  272.             n = bi.biClrUsed;
  273.         //
  274.         //  A DIB color table has its colors stored BGR not RGB
  275.         //  so flip them around.
  276.         //
  277.         for (i = 0; i < n; i++)
  278.         {
  279.             BYTE        r = ape[i].peRed;
  280.  
  281.             ape[i].peRed = ape[i].peBlue;
  282.             ape[i].peBlue = r;
  283.         }
  284.     }
  285.     pdd->CreatePalette(DDPCAPS_8BIT, ape, &ddpal, NULL);
  286.     return ddpal;
  287. }
  288.  
  289.  
  290.  
  291.  
  292. //-----------------------------------------------------------------------------
  293. // Name: DDColorMatch()
  294. // Desc: Convert a RGB color to a pysical color.
  295. //       We do this by leting GDI SetPixel() do the color matching
  296. //       then we lock the memory and see what it got mapped to.
  297. //-----------------------------------------------------------------------------
  298. extern "C" DWORD
  299. DDColorMatch(IDirectDrawSurface7 * pdds, COLORREF rgb)
  300. {
  301.     COLORREF                rgbT;
  302.     HDC                     hdc;
  303.     DWORD                   dw = CLR_INVALID;
  304.     DDSURFACEDESC2          ddsd;
  305.     HRESULT                 hres;
  306.  
  307.     //
  308.     //  Use GDI SetPixel to color match for us
  309.     //
  310.     if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
  311.     {
  312.         rgbT = GetPixel(hdc, 0, 0);     // Save current pixel value
  313.         SetPixel(hdc, 0, 0, rgb);       // Set our value
  314.         pdds->ReleaseDC(hdc);
  315.     }
  316.     //
  317.     // Now lock the surface so we can read back the converted color
  318.     //
  319.     ddsd.dwSize = sizeof(ddsd);
  320.     while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
  321.         ;
  322.     if (hres == DD_OK)
  323.     {
  324.         dw = *(DWORD *) ddsd.lpSurface;                 // Get DWORD
  325.         if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
  326.             dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;  // Mask it to bpp
  327.         pdds->Unlock(NULL);
  328.     }
  329.     //
  330.     //  Now put the color that was there back.
  331.     //
  332.     if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
  333.     {
  334.         SetPixel(hdc, 0, 0, rgbT);
  335.         pdds->ReleaseDC(hdc);
  336.     }
  337.     return dw;
  338. }
  339.  
  340.  
  341.  
  342.  
  343. //-----------------------------------------------------------------------------
  344. // Name: DDSetColorKey()
  345. // Desc: Set a color key for a surface, given a RGB.
  346. //       If you pass CLR_INVALID as the color key, the pixel
  347. //       in the upper-left corner will be used.
  348. //-----------------------------------------------------------------------------
  349. extern "C" HRESULT
  350. DDSetColorKey(IDirectDrawSurface7 * pdds, COLORREF rgb)
  351. {
  352.     DDCOLORKEY              ddck;
  353.  
  354.     ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
  355.     ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
  356.     return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
  357. }
  358.  
  359.